﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Excel;
using System.Xml;
using System.Collections.ObjectModel;
using Microsoft.Office.Core;
using System.Reflection;
using System.IO;
using System.Runtime.InteropServices;
using LightingServer.Tool;

namespace LightingServer.TemplateGenerator
{
    public class ListGenerator : AbstractGenerator
    {
        protected override string TemplateName
        {
            get { return "灯具清单"; }
        }

        private static readonly Dictionary<string, PropertyInfo> _methods;

        static ListGenerator()
        {
            _methods = new Dictionary<string, PropertyInfo>();

            Type type = typeof(Picture);
            _methods[FacadeXpath] = type.GetProperty("Facade");
            _methods[SizeXpath] = type.GetProperty("Size");
            _methods[GradingXpath] = type.GetProperty("Grading1");
            _methods[LiveXpath] = type.GetProperty("Live");
        }

        public byte[] Generate(Lightings lightings, bool convertPDF = false)
        {
            Excel.Application application = null;

            Excel.Workbook wb = null;
            string exportFile = null;
            try
            {
                LogTool.Log("1 复制模板......");

                string dateTime = DateTime.Now.ToString("yyyyMMddHHmmss");
                exportFile = TemplateName + dateTime + ".xlsx";
                string sourceFile = Path.Combine(LightingServerContext.TemplateRoot, TemplateName + ".xlsx");
                string temFile = Path.Combine(LightingServerContext.ExportRoot, exportFile);
                File.Copy(sourceFile, temFile, true);

                application = new Excel.Application();
                application.Visible = false;

                LogTool.Log("2 加载模板......");
                wb = application.Workbooks.Open(temFile);
                Excel.Worksheet sheet = wb.Sheets[1];
                Excel.XmlMap map = SearchMap(wb, ListMapName);

                List<Excel.ListColumn> columns = new List<Excel.ListColumn>();
                foreach (Excel.ListObject listObject in sheet.ListObjects)
                {
                    foreach (Excel.ListColumn listColumn in listObject.ListColumns)
                    {
                        string xpath = listColumn.XPath.Value;
                        if (_methods.ContainsKey(xpath))
                            MappingPictures(sheet, listColumn.Range, lightings, _methods[xpath]);
                    }
                }

                LogTool.Log("4 插入数据......");
                string xmlData = ConvertToXml(lightings);
                map.ImportXml(xmlData);

                LogTool.Log("5 保存......");
                wb.Save();
                if (convertPDF)
                {
                    exportFile = TemplateName + dateTime + ".pdf";

                    //wb.SaveAs(pdfFile, Excel.XlFixedFormatType.xlTypePDF);
                    wb.ExportAsFixedFormat(
                    Microsoft.Office.Interop.Excel.XlFixedFormatType.xlTypePDF,
                    Path.Combine(LightingServerContext.ExportRoot, exportFile),
                    Microsoft.Office.Interop.Excel.XlFixedFormatQuality.xlQualityStandard,
                    false,
                    false,
                    System.Reflection.Missing.Value,
                    System.Reflection.Missing.Value,
                    false,
                    System.Reflection.Missing.Value);
                    try
                    {
                        File.Delete(temFile);
                    }
                    catch
                    {
                    }
                }
            }
            catch (Exception ex)
            {

            }
            finally
            {
                try
                {
                    wb.Close();
                    Marshal.ReleaseComObject(wb);
                }
                catch
                {
                }

                try
                {
                    application.Quit();
                    Marshal.ReleaseComObject(wb);
                    Kill(application);
                }
                catch
                {
                }
            }

            exportFile = Path.Combine(LightingServerContext.ExportUrl, exportFile);
            return Encoding.UTF8.GetBytes(exportFile);
        }

        private void MappingPictures(Excel.Worksheet sheet, Excel.Range range, Lightings lightings, PropertyInfo propertyInfo)
        {
            int row = range.Row;
            int colum = range.Column;

            foreach (Lighting lighting in lightings.LightingList)
            {
                if (lighting.HasPicture)
                {
                    try
                    {
                        string imageName = (string)propertyInfo.GetValue(lighting.Picture, null);
                        if (!string.IsNullOrEmpty(imageName))
                        {
                            Excel.Range selectedRange = sheet.Cells[++row, colum];
                            imageName = imageName.Remove(0, LightingServerContext.ImageUrl.Length);
                            string imageUrl = Path.Combine(LightingServerContext.ImageRoot, imageName);
                            SetWorksheetImage(sheet, selectedRange, imageUrl);
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }

        private string ConvertToXml(Lightings lightings)
        {
            StringBuilder sb = new StringBuilder();
            using (XmlWriter writer = XmlWriter.Create(sb))
            {
                writer.WriteStartElement("灯具的相关表");
                Write(writer, lightings);
                writer.WriteEndElement();
                writer.Flush();
            }
            return sb.ToString();
        }

        private void Write(XmlWriter xmlWriter, Lightings lightings)
        {
            int index = 0;
            foreach (Lighting data in lightings.LightingList)
            {
                index++;
                xmlWriter.WriteStartElement("基本信息");
                xmlWriter.WriteStartElement("序号");
                xmlWriter.WriteValue(index);
                xmlWriter.WriteEndElement();
                xmlWriter.WriteElementString("产品品牌", data.Lable);
                xmlWriter.WriteElementString("产品系列", data.Series);

                //ResItem clsItem = (from r in ResourceProvider.ProductTypes
                //                   where r.ItemID== data.Class
                //                   select r).SingleOrDefault();
                //xmlWriter.WriteElementString("产品分类", clsItem != null ? clsItem.ItemName : string.Empty);
                xmlWriter.WriteElementString("规格型号", data.Version);

                ResItem orginItem = (from r in ResourceProvider.Orgin
                                     where r.ItemID == data.Orgin
                                     select r).SingleOrDefault();
                xmlWriter.WriteElementString("产地", orginItem != null ? orginItem.ItemName : string.Empty);

                ResItem placeItem = (from r in ResourceProvider.UseArea
                                     where r.ItemID == data.Place
                                     select r).SingleOrDefault();
                xmlWriter.WriteElementString("使用场所", placeItem != null ? placeItem.ItemName : string.Empty);

                ResItem clsItem = (from r in ResourceProvider.LightingType
                                   where r.ItemID == data.AdapterLighting.Class
                                   select r).SingleOrDefault();
                xmlWriter.WriteElementString("光源种类", clsItem != null ? clsItem.ItemName : string.Empty);
                xmlWriter.WriteElementString("光源型号", data.AdapterLighting.Version);
                xmlWriter.WriteElementString("色温或颜色", data.AdapterLighting.Color);
                xmlWriter.WriteElementString("显色性", data.AdapterLighting.Cri.ToString());
                xmlWriter.WriteElementString("光输出", data.AdapterLighting.Output.ToString());
                xmlWriter.WriteElementString("插脚形式", data.AdapterLighting.Pins);

                xmlWriter.WriteElementString("材质说明", data.Physical.Material);
                xmlWriter.WriteElementString("外观颜色", data.Physical.Color);
                xmlWriter.WriteElementString("外形尺寸", data.Physical.Size);
                xmlWriter.WriteElementString("防护等级", data.Physical.Defend);

                ResItem impactItem = (from r in ResourceProvider.DefendType
                                      where r.ItemID == data.Physical.Impact
                                      select r).SingleOrDefault();
                xmlWriter.WriteElementString("防撞击等级", impactItem != null ? impactItem.ItemName : string.Empty);
                xmlWriter.WriteElementString("产品重量", data.Physical.Weight.ToString());

                ResItem explainItem = (from r in ResourceProvider.LightingExplain
                                       where r.ItemID == data.Optics.Explain
                                       select r).SingleOrDefault();
                xmlWriter.WriteElementString("配光说明", explainItem != null ? explainItem.ItemName : string.Empty);
                xmlWriter.WriteElementString("光束角", data.Optics.Angle.ToString());
                xmlWriter.WriteElementString("灯具效率", data.Optics.Efficiency.ToString());

                xmlWriter.WriteElementString("防触电等级", data.Electric.Shock);

                ResItem voltageItem = (from r in ResourceProvider.WorkVoltage
                                       where r.ItemID == data.Electric.Voltage
                                       select r).SingleOrDefault();
                xmlWriter.WriteElementString("工作电压", voltageItem != null ? voltageItem.ItemName : string.Empty);

                xmlWriter.WriteElementString("电器类型", data.Electric.Type);
                xmlWriter.WriteElementString("电器功耗", data.Electric.ElectricPower.ToString());
                xmlWriter.WriteElementString("光源功率", data.Electric.LightingPower.ToString());
                xmlWriter.WriteElementString("整灯功耗", data.Electric.AllPower.ToString());

                ResItem controlItem = (from r in ResourceProvider.ControlType
                                       where r.ItemID == data.Electric.ControlType
                                       select r).SingleOrDefault();
                xmlWriter.WriteElementString("控制方式", controlItem != null ? controlItem.ItemName : string.Empty);

                ResItem setupItem = (from r in ResourceProvider.SetupType
                                     where r.ItemID == data.Project.Setup
                                     select r).SingleOrDefault();
                xmlWriter.WriteElementString("安装方式", setupItem != null ? setupItem.ItemName : string.Empty);
                xmlWriter.WriteElementString("安装尺寸", data.Project.Size);
                //xmlWriter.WriteElementString("认证及检测报告", data.Project.Report);
                xmlWriter.WriteElementString("备注", data.Project.Baikup);
                xmlWriter.WriteElementString("可选配件", data.Project.Parts);

                //xmlWriter.WriteElementString("参考进价", data.Business.In.ToString());
                //xmlWriter.WriteElementString("市场参考价", data.Business.Market.ToString());
                xmlWriter.WriteElementString("参考售价", data.Business.Out.ToString());
                xmlWriter.WriteElementString("参考货期", data.Business.Delievery);
                xmlWriter.WriteEndElement();
            }
        }
    }

}
